package dk.pun.dums.client.presenter;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;

import dk.pun.dums.client.DUMSServiceAsync;
import dk.pun.dums.client.event.CharacterDeletedEvent;
import dk.pun.dums.client.event.CharacterRenamedEvent;
import dk.pun.dums.client.event.CharacterSelectedEvent;
import dk.pun.dums.client.event.SelectCharacterEventHandler;
import dk.pun.dums.client.view.SelectCharacterView;
import dk.pun.dums.shared.character.CharacterData;
import dk.pun.dums.shared.user.UserData;

public class SelectCharacterPresenter implements Presenter, SelectCharacterView.Presenter {

	private final transient SelectCharacterView view;
	private final transient SelectCharacterEventHandler eventHandler;
	private final transient UserData userData;
	private final transient DUMSServiceAsync rpcService;

	public SelectCharacterPresenter(final SelectCharacterView view, final SelectCharacterEventHandler eventHandler, final UserData userData, final DUMSServiceAsync rpcService) {
		this.view = view;
		this.view.setPresenter(this);
		this.eventHandler = eventHandler;
		this.userData = userData;
		this.rpcService = rpcService;

		this.rpcService.findCharacterDataByUserKey(userData.getKey(), new AsyncCallback<List<CharacterData>>() {

			@Override
			public void onSuccess(List<CharacterData> result) {
				view.setCharacters(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				GWT.log("Failed to get characters: ", caught);
			}
		});
	}
	
	@Override
	public void onCharacterSelected(final CharacterData characterData) {
		eventHandler.onCharacterSelected(new CharacterSelectedEvent(characterData));
	}

	@Override
	public void onCharacterAdded(final String name) {
		this.rpcService.createCharacterData(name, this.userData.getKey(), new AsyncCallback<CharacterData>() {

			@Override
			public void onSuccess(final CharacterData result) {
				view.addCharacter(result);
				onCharacterSelected(result);
			}

			@Override
			public void onFailure(final Throwable caught) {
				GWT.log("Failed to add character: ", caught);
			}
		});
	}

	@Override
	public void onCharacterRenamed(final CharacterData characterData, final String oldName) {
		this.rpcService.updateCharacterData(characterData, new AsyncCallback<Void>() {

			@Override
			public void onSuccess(final Void result) {
				view.refreshCharacterView();
				eventHandler.onCharacterRenamed(new CharacterRenamedEvent(characterData, oldName));
			}

			@Override
			public void onFailure(final Throwable caught) {
				GWT.log("Failed to update user data: ", caught);
			}
		});
	}

	@Override
	public void onCharacterDeleted(final CharacterData characterData) {
		this.rpcService.deleteCharacterData(characterData.getKey(), new AsyncCallback<Void>() {

			@Override
			public void onSuccess(final Void result) {
				view.removeCharacter(characterData);
				eventHandler.onCharacterDeleted(new CharacterDeletedEvent(characterData));
			}

			@Override
			public void onFailure(final Throwable caught) {
				GWT.log("Failed to delete character: ", caught);
			}
		});
	}

	@Override
	public void onCharacterStatusUpdated(final CharacterData characterData) {
		this.rpcService.updateCharacterData(characterData, new AsyncCallback<Void>() {

			@Override
			public void onSuccess(final Void result) {
				// Nothing to do on success.
			}

			@Override
			public void onFailure(final Throwable caught) {
				GWT.log("Failed to update character data: ", caught);
			}
		});
	}
	
	@Override
	public void go(final HasWidgets container) {
		container.clear();
		container.add(this.view.asWidget());
	}
	
}
